package com.mz.mattress.admin.interceptor;

import com.mz.mattress.api.common.Constants;
import com.mz.mattress.api.util.JacksonUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 请求参数，出参，方法耗时等日志统计
 */
@Aspect
@Component
@Slf4j
public class ApiLogAspect {

    public static final String EXPRESSION = "execution(public * com.mz.mattress.admin.api.*.*(..)) || execution(public * com.mz.mattress.admin.api.admin.*.*(..)) || execution(public * com.mz.mattress.admin.api.merchant.*.*(..))";

    @Pointcut(EXPRESSION)
    public void controllerAspect() {

    }

    private volatile Integer showFullLog = 1;

    public void changeLog() {
        showFullLog = showFullLog == 0 ? 1 : 0;
    }

    @Around("controllerAspect()")
    public Object doControllerAround(ProceedingJoinPoint jp) throws Throwable {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        long beginTime = System.currentTimeMillis();
        int random = ThreadLocalRandom.current().nextInt(9999) + 1000;
        StringBuilder sb = new StringBuilder(512);
        // 打印请求内容
        filled(sb, Constants.REQUEST_TOKEN, random, request.getHeader(Constants.LOGIN_TOKEN_KEY));
        filled(sb, Constants.REQUEST_IP, random, request.getRemoteAddr());
        filled(sb, Constants.REQUEST_URL, random, request.getRequestURL().toString());
//        filled(sb, Constants.REQUEST, random, request.getMethod());
        filled(sb, Constants.REQUEST_METHOD, random, jp.getSignature().toString());
        filled(sb, Constants.REQUEST_ARGS, random, Arrays.toString(jp.getArgs()));
        log.info(sb.toString());

        Object result = jp.proceed();
        long endTime = System.currentTimeMillis();

        // 取消二维码打印
        if (jp.getSignature().toString().contains("qrCode")) {
            return result;
        }

        String content = JacksonUtils.toJson(result);
        int length = content.length();
        sb = new StringBuilder(length + 50);

        log.info("showFullLog=" + showFullLog);
        if (showFullLog == 1) {
            filled(sb, Constants.RESPONSE_TIME, random, (endTime - beginTime) + "");
            filled(sb, Constants.RESPONSE_CONTENT, random, content);
        } else {
            if (content != null && length > 1500) {
                filled(sb, Constants.REQUEST_METHOD, random, jp.getSignature().toString() + ",large_content=" + length);
            } else {
                filled(sb, Constants.RESPONSE_TIME, random, (endTime - beginTime) + "");
                filled(sb, Constants.RESPONSE_CONTENT, random, content);
            }
        }

        log.info(sb.toString());
        return result;
    }

    private void filled(StringBuilder sb, String key, int random, String val) {
        sb.append("\n").append(random).append("_").append(key).append("=").append(val);
    }

}
